import { ApiProperty } from "@nestjs/swagger";
import { SysUser } from "@prisma/client";
import { Transform } from "class-transformer";
import {
    IsBoolean,
    IsEmail,
    IsInt,
    IsNotEmpty,
    IsNumberString,
    IsOptional,
    IsString,
    Length,
    Matches,
    Min,
    MinLength
} from "class-validator";

import { DbCommonField } from "@/core/types/db-common-field.type";

export class CreateSysUserDto
    implements CustomOmit<SysUser, "id" | "realname" | "gender" | "lastLoginAt" | "lastLoginIp" | DbCommonField>
{
    @Transform(({ value }) => value.trim())
    @Matches(/^[a-zA-Z0-9_]+$/, { message: "用户名只能包含字母、数字、下划线" })
    @IsString()
    @IsNotEmpty({ message: "用户名不能为空" })
    @MinLength(1, { message: "用户名至少1个字符" })
    @ApiProperty({
        description: "登录用户名，用户名只能包含字母、数字、下划线",
        example: "JohnDoe",
        required: true
    })
    username: string;

    @IsEmail({}, { message: "邮箱格式不正确" })
    @IsNotEmpty({ message: "邮箱不能为空" })
    @ApiProperty({
        description: "邮箱地址",
        example: "john.doe@example.com",
        required: true
    })
    email: string;

    @IsString()
    @IsNotEmpty({ message: "密码不能为空" })
    @MinLength(6, { message: "密码至少6个字符" })
    @ApiProperty({
        description: "密码",
        example: "password123",
        required: true
    })
    password: string;

    @IsString()
    @IsNotEmpty({ message: "昵称不能为空" })
    @MinLength(1, { message: "昵称至少1个字符" })
    @ApiProperty({
        description: "昵称",
        example: "用户123",
        required: true
    })
    nickname: string;

    @IsString()
    @IsOptional()
    @ApiProperty({
        description: "头像URL",
        example: "`https://api.dicebear.com/9.x/lorelei/svg?seed=${Date.now()}`",
        required: false,
        default: "`https://api.dicebear.com/9.x/lorelei/svg?seed=${Date.now()}`"
    })
    avatar: string;

    @IsNumberString()
    @IsOptional()
    @Length(11, 11)
    @ApiProperty({
        description: "手机号",
        example: "13800138000",
        required: false
    })
    phone: string;

    @Transform(({ value }) => {
        if (value === "1" || value === "yes" || value === "true") return true;
        if (value === "0" || value === "no" || value === "false") return false;
        return value;
    })
    @IsBoolean()
    @IsOptional()
    @ApiProperty({
        description: "是否固定用户",
        example: false,
        required: false
    })
    isFixed: boolean;

    @Transform(({ value }) => Number(value))
    @IsInt()
    @Min(0, { message: "状态必须为大于等于0的整数" })
    @IsOptional()
    @ApiProperty({
        description: "排序",
        example: 1,
        required: false
    })
    sort: number;

    @Transform(({ value }) => {
        if (value === "1" || value === "yes" || value === "true") return true;
        if (value === "0" || value === "no" || value === "false") return false;
        return value;
    })
    @IsBoolean()
    @IsOptional()
    @ApiProperty({
        description: "是否允许多点登录",
        example: false,
        required: false
    })
    isMultipoint: boolean;

    @Transform(({ value }) => {
        if (value === "1" || value === "yes" || value === "true") return true;
        if (value === "0" || value === "no" || value === "false") return false;
        return value;
    }) // 在 QueryDto 中，参数是以 URL 中的查询参数携带，而 URL 都是字符串类型"false"/"true"，所以需要转换一下
    @IsBoolean()
    @IsOptional()
    @ApiProperty({
        description: "是否禁用",
        example: false,
        required: false
    })
    isDisabled: boolean;

    @Transform(({ value }) => {
        if (value === "1" || value === "yes" || value === "true") return true;
        if (value === "0" || value === "no" || value === "false") return false;
        return value;
    })
    @IsBoolean()
    @IsOptional()
    @ApiProperty({
        description: "是否超级管理员",
        example: false,
        type: Boolean,
        required: false
    })
    isSuper: boolean;
}
